package com.kingstar.ceres.memory;

import com.kingstar.ceres.entity.secondary.*;
import com.kingstar.constants.MessageType;
import com.kingstar.entity.BasicQuote;
import com.kingstar.entity.cmds.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

@Slf4j
public class MessageMemory {


    /**
     * 五张表缓存队列
     */
    public static final BlockingQueue<KCmdsBondMarketDeal> BOND_MARKET_DEAL_QUEUE=new LinkedBlockingQueue();
    public static final BlockingQueue<KCmdsIrsMarketDeal> IRS_MARKET_DEAL_QUEUE=new LinkedBlockingQueue();
    public static final BlockingQueue<KCmdsMarketDataSummaryBond> MARKET_DATA_SUMMARY_BOND_QUEUE=new LinkedBlockingQueue();
    public static final BlockingQueue<KCmdsXbondMarketDeal> XBOND_MARKET_DEAL_QUEUE=new LinkedBlockingQueue();
    public static final BlockingQueue<KCmdsXswapMarketDeal> XSWAP_MARKET_DEAL_QUEUE=new LinkedBlockingQueue();

    public static void put(BasicQuote basicQuote){
        String type = basicQuote.getType();

        switch (type){
            case MessageType.CMDS_MARKET_DATA_XBOND:
                parseXBondMarketDeal(basicQuote);
                break;
            case MessageType.CMDS_MARKET_DATA_XSWAP:
                parseXSwapMarketDeal(basicQuote);
                break;
            case MessageType.CMDS_MARKET_DATA_BOND_SUMMARY:
                parseSummaryBond(basicQuote);
                break;
            case MessageType.CMDS_EXECUTION_BOND:
                parseBondMarketDeal(basicQuote);
                break;
            case MessageType.CMDS_EXECUTION_IRS:
                parseIrsMarketDeal(basicQuote);
                break;
            default:
                break;
        }
    }

    private static void parseIrsMarketDeal(BasicQuote basicQuote) {
        MarketDealIRS quote=(MarketDealIRS)basicQuote;
        KCmdsIrsMarketDeal entity=KCmdsIrsMarketDeal.builder()
                .benchmarkSpread(getDecimal(quote.getBenchmarkSpread()))
                .createTime(quote.getCreateTimeMillis())
                .execId(quote.getExecId())
                .execType(quote.getExecType())
                .fixRate(getDecimal(quote.getFixRate()))
                .fixSide(quote.getFixSide())
                .floatBenchmarkCurvename(quote.getFloatBenchmarkCurvename())
                .floatSide(quote.getFloatSide())
                .marketIndicator(quote.getMarketIndicator())
                .messageSource(quote.getMessageSource())
                .lastQty(getDecimal(quote.getLastQty()))
                .quotationTime(getDateTimeLong(quote.getTransactTime()))
                .securityId(quote.getSecurityID())
                .side(quote.getSide())
                .symbol(quote.getSymbol())
                .tradeDate(getDateStr(quote.getTransactTime()))
                .tradeLimitDayes(quote.getTradeLimitDays())
                .tradeTime(quote.getTradeTime())
                .transactTime(quote.getTransactTime())
                .build();
        IRS_MARKET_DEAL_QUEUE.offer(entity);
    }

    private static void parseBondMarketDeal(BasicQuote basicQuote) {
        MarketDealBond quote=(MarketDealBond)basicQuote;
        KCmdsBondMarketDeal entity=KCmdsBondMarketDeal.builder()
                .createTime(quote.getCreateTimeMillis())
                .execId(quote.getExecId())
                .execType(quote.getExecType())
                .lastQty(getInt(quote.getLastQty()))
                .marketIndicator(quote.getMarketIndicator())
                .messageSource(quote.getMessageSource())
                .preMarketBondIndicator(quote.getPreMarketBondIndicator())
                .price(getDecimal(quote.getPrice()))
                .quotationTime(getDateTimeLong(quote.getTransactTime()))
                .securityId(quote.getSecurityID())
                .stipulationType(quote.getStipulationType())
                .stipulationValue(quote.getStipulationValue())
                .symbol(quote.getSymbol())
                .tradeDate(quote.getTradeDate())
                .tradeMethod(quote.getTradeMethod())
                .tradeTime(quote.getTradeTime())
                .tradeType(quote.getTradeType())
                .transactionMethod(quote.getTransactionMethod())
                .transactTime(quote.getTransactTime())
                .build();
        BOND_MARKET_DEAL_QUEUE.offer(entity);

    }

    private static void parseSummaryBond(BasicQuote basicQuote) {
        MarketDataSummaryBond quote=(MarketDataSummaryBond)basicQuote;
        KCmdsMarketDataSummaryBond entity=KCmdsMarketDataSummaryBond.builder()
                .closePrice(getDecimal(quote.getClosePrice()))
                .closeYield(getDecimal(quote.getCloseYield()))
                .createTime(quote.getCreateTimeMillis())
                .dealNum(getDecimal(quote.getDealNum()))
                .dealTotal(getInt(quote.getDealTotal()))
                .highPrice(getDecimal(quote.getHighPrice()))
                .highYield(getDecimal(quote.getHighYield()))
                .lowerPrice(getDecimal(quote.getLowerPrice()))
                .lowerYield(getDecimal(quote.getLowerYield()))
                .marketIndicator(quote.getMarketIndicator())
                .mdSubType(quote.getMdSubType())
                .mdType(quote.getMdType())
                .messageSource(quote.getMessageSource())
                .newPrice(getDecimal(quote.getNewPrice()))
                .newYield(getDecimal(quote.getNewYield()))
                .openPrice(getDecimal(quote.getOpenPrice()))
                .openYield(getDecimal(quote.getOpenYield()))
                .other(quote.getOther())
                .preCloPrice(getDecimal(quote.getPreCloPrice()))
                .preCloseYield(getDecimal(quote.getPreCloseYield()))
                .preWeightAvgPrice(getDecimal(quote.getWeightAvgPrice()))
                .preWeightAvgYield(getDecimal(quote.getWeightAvgYield()))
                .priceChange(getDecimal(quote.getPriceChange()))
                .priceChangeWave(getDecimal(quote.getPriceChangeWave()))
                .quotationTime(getDateTimeLong(quote.getTransactTime()))
                .securityId(quote.getSecurityID())
                .symbol(quote.getSymbol())
                .termToMaturity(quote.getTermToMaturity())
                .tradeDate(getDateStr(quote.getTransactTime()))
                .tradeMethod(quote.getTradeMethod())
                .tradeTime(getDateTimeStr(quote.getTransactTime()))
                .transactTime(quote.getTransactTime())
                .weightAvgPrice(getDecimal(quote.getWeightAvgPrice()))
                .weightAvgYield(getDecimal(quote.getWeightAvgYield()))
                .yieldChange(getDecimal(quote.getYieldChange()))
                .build();
        MARKET_DATA_SUMMARY_BOND_QUEUE.offer(entity);
    }

    private static void parseXSwapMarketDeal(BasicQuote basicQuote) {
        MarketDataDealXSwap quote=(MarketDataDealXSwap)basicQuote;
        KCmdsXswapMarketDeal entity=KCmdsXswapMarketDeal.builder()
                .createTime(quote.getCreateTimeMillis())
                .dealSizeOfDay(getInt(quote.getDealSizeOfDay()))
                .lastAllInDealtRate(getDecimal(quote.getLastAllInDealtRate()))
                .marketIndicator(quote.getMarketIndicator())
                .mdSubType(quote.getMdSubType())
                .messageSource(quote.getMessageSource())
                .mdType(quote.getMdType())
                .openingPrice(getDecimal(quote.getOpeningPrice()))
                .quotationTime(getDateTimeLong(quote.getTransactTime()))
                .securityId(quote.getSecurityID())
                .sessionReferencePrice(getDecimal(quote.getSessionReferencePrice()))
                .tradeDate(getDateStr(quote.getTransactTime()))
                .tradeMethod(quote.getTradeMethod())
                .tradeTime(getDateTimeStr(quote.getTransactTime()))
                .tradeVolume(getInt(quote.getTradeVolume()))
                .tradingSessionHighDealtPrice(getDecimal(quote.getTradingSessionHighDealtPrice()))
                .tradingSessionLowDealtPrice(getDecimal(quote.getTradingSessionLowDealtPrice()))
                .transactTime(quote.getTransactTime())
                .build();
        XSWAP_MARKET_DEAL_QUEUE.offer(entity);
    }

    private static void parseXBondMarketDeal(BasicQuote basicQuote) {
        MarketDataDealXBond quote=(MarketDataDealXBond)basicQuote;
        KCmdsXbondMarketDeal entity=KCmdsXbondMarketDeal.builder()
                .beforeClosingPrice(getDecimal(quote.getBeforeClosingPrice()))
                .beforeClosingYield(getDecimal(quote.getBeforeClosingYield()))
                .beforeOpeningPrice(getDecimal(quote.getBeforeOpeningPrice()))
                .beforeOpeningYield(getDecimal(quote.getBeforeOpeningYield()))
                .beforeWeightedAveragePrice(getDecimal(quote.getBeforeWeightedAveragePrice()))
                .beforeWeightedAverageYield(getDecimal(quote.getBeforeWeightedAverageYield()))
                .createTime(quote.getCreateTimeMillis())
                .fillSide(quote.getFillSide())
                .highestPrice(getDecimal(quote.getHighestPrice()))
                .highestYield(getDecimal(quote.getHighestYield()))
                .lowestPrice(getDecimal(quote.getLowestPrice()))
                .lowestYield(getDecimal(quote.getLowestYield()))
                .marketIndicator(quote.getMarketIndicator())
                .mdSubType(quote.getMdSubType())
                .messageSource(quote.getMessageSource())
                .mdType(quote.getMdType())
                .openingPrice(getDecimal(quote.getOpeningPrice()))
                .openingValence(getDecimal(quote.getOpeningValence()))
                .openingYield(getDecimal(quote.getOpeningYield()))
                .preMarketBondIndicator(quote.getPreMarketBondIndicator())
                .priceRiseFallAmplitude(getDecimal(quote.getPriceRiseFallAmplitude()))
                .quotationTime(getDateTimeLong(quote.getTransactTime()))
                .securityId(quote.getSecurityID())
                .settlType(quote.getSettlType())
                .symbol(quote.getSymbol())
                .tradeDate(getDateStr(quote.getTransactTime()))
                .tradeMethod(quote.getTradeMethod())
                .tradeTime(getDateTimeStr(quote.getTransactTime()))
                .transactionNumber(getInt(quote.getTransactionNumber()))
                .transactTime(quote.getTransactTime())
                .upToDatePrice(getDecimal(quote.getUpToDatePrice()))
                .upToDateYield(getDecimal(quote.getUpToDateYield()))
                .weightedAveragePrice(getDecimal(quote.getWeightedAveragePrice()))
                .weightedAverageYield(getDecimal(quote.getWeightedAverageYield()))
                .yieldRiseFall(getDecimal(quote.getYieldRiseFall()))
                .build();
        XBOND_MARKET_DEAL_QUEUE.offer(entity);
    }

    private static BigDecimal getDecimal(String str){
        if (StringUtils.isEmpty(str)){
            return null;
        }
        return new BigDecimal(str);
    }

    private static String getDateStr(String str){
        if (StringUtils.isEmpty(str)){
            return null;
        }
        return  str.substring(0, 8);
    }

    private static String getDateTimeStr(String str){
        if (StringUtils.isEmpty(str)){
            return null;
        }
        return str.substring(9, 17);
    }

    private static Long getDateTimeLong(String str){
        if (StringUtils.isEmpty(str)){
            return null;
        }
        SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd-HH:mm:ss.sss");
        try {
            Date date = format.parse(str);
            return date.getTime()/1000;
        } catch (ParseException e) {
            log.warn("time parse err");
            return null;
        }
    }

    private static Long getInt(String str){
        if (StringUtils.isEmpty(str)){
            return null;
        }
//        return Integer.parseInt(str);
        return Long.parseLong(str);
    }
}
